package com.tjmc.company.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tjmc.company.api.entity.CompanyInfoEntity;
import com.tjmc.company.api.entity.JobInfoEntity;
import com.tjmc.company.api.enums.DegreeEnum;
import com.tjmc.company.api.enums.JobStatusEnum;
import com.tjmc.company.api.enums.WorkExperienceEnum;
import com.tjmc.company.api.vo.JobTopVO;
import com.tjmc.company.service.CompanyInfoService;
import com.tjmc.company.service.JobInfoService;
import com.tjmc.recruit.admin.api.entity.PlatformUserInfoEntity;
import com.tjmc.recruit.admin.api.enums.PlatUserTypeEnum;
import com.tjmc.recruit.admin.api.feign.RemoteUserService;
import com.tjmc.recruit.common.core.constant.CommonConstants;
import com.tjmc.recruit.common.core.constant.SecurityConstants;
import com.tjmc.recruit.common.core.util.R;
import com.tjmc.recruit.common.log.annotation.SysLog;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import com.pig4cloud.plugin.excel.annotation.RequestExcel;

import com.tjmc.recruit.common.security.annotation.Inner;
import com.tjmc.recruit.common.security.util.SecurityUtils;
import com.tjmc.recruit.finance.api.entity.PlatformUserAccountEntity;
import com.tjmc.recruit.finance.api.feign.RemoteAccountService;
import com.tjmc.recruit.user.feign.PersonalCollectService;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import jakarta.validation.Valid;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.tjmc.company.service.impl.JobInfoServiceImpl.JOB_REFRESH_INFO_PREFIX;
import static com.tjmc.company.service.impl.JobInfoServiceImpl.JOB_REFRESH_KEY;

/**
 * 职位信息表
 *
 * @author recruit
 * @date 2024-11-14 17:07:26
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/jobInfo")
@Tag(description = "jobInfo", name = "职位信息表管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class JobInfoController {

    private final JobInfoService jobInfoService;
    private final RedisTemplate<String, Object> redisTemplate;
    private final PersonalCollectService personalCollectService;
    private final RemoteUserService remoteUserService;
    private final RemoteAccountService remoteAccountService;

    /**
     * 分页查询
     *
     * @param page    分页对象
     * @param jobInfo 职位信息表
     * @return
     */
    @Operation(summary = "分页查询", description = "分页查询")
    @GetMapping("/page")
    public R getJobInfoPage(@ParameterObject Page page, @ParameterObject JobInfoEntity jobInfo) {
        //用户是否为主账号
        R<PlatformUserInfoEntity> platformedUser = remoteUserService.platformUser(SecurityUtils.getUser().getName(), SecurityConstants.FROM_IN);
        if (platformedUser.getData().getAccountType().equals(PlatUserTypeEnum.MAIN)) {
            jobInfo.setCreatedBy(null);
        } else {
            jobInfo.setCreatedBy(String.valueOf(platformedUser.getData().getId()));
        }
        LambdaQueryWrapper<JobInfoEntity> wrapper = Wrappers.lambdaQuery(jobInfo);
        wrapper.eq(JobInfoEntity::getStatus, JobStatusEnum.PUBLISHED);
        return R.ok(jobInfoService.selectCompanyJobPage(page, wrapper));
    }

    /**
     * 行业类别查询职位
     *
     * @param page    分页对象
     * @param jobInfo 职位信息表
     * @return
     */
    @Operation(summary = "行业类别查询职位", description = "行业类别查询职位")
    @GetMapping("/page/jobCategory")
    public R getJobInfoPageByCategory(@ParameterObject Page page, @ParameterObject JobInfoEntity jobInfo) {
        LambdaQueryWrapper<JobInfoEntity> wrapper = new LambdaQueryWrapper<JobInfoEntity>()
                .like(StrUtil.isNotBlank(jobInfo.getJobCategory()), JobInfoEntity::getJobCategory, jobInfo.getJobCategory())
                .eq(JobInfoEntity::getStatus, JobStatusEnum.PUBLISHED);
        return R.ok(jobInfoService.page(page, wrapper));
    }

    /**
     * 查询企业职位列表
     *
     * @param companyId
     * @return
     */
    @Operation(summary = "查询企业职位列表", description = "查询企业职位列表")
    @GetMapping("/list/{companyId}")
    @Inner
    @SysLog("查询企业职位列表")
    public R getJobListByCompanyId(@PathVariable String companyId) {
        return R.ok(jobInfoService.list(new LambdaQueryWrapper<JobInfoEntity>().eq(JobInfoEntity::getCompanyId, companyId)));
    }

    @Operation(summary = "查询企业置顶职位列表", description = "查询企业置顶职位列表")
    @GetMapping("/topPage/{companyId}")
    @SysLog("查询企业置顶职位列表")
    public R getTopPage(@PathVariable String companyId, @ParameterObject Page page) {
        return R.ok(jobInfoService.selectTopJobPage(page, Long.valueOf(companyId)));
    }

    /**
     * 查询个人用户推荐职位
     *
     * @param page      分页条件
     * @param jobIntent 意向岗位
     * @return
     */
    @Operation(summary = "查询个人用户推荐职位", description = "查询个人用户推荐职位")
    @SysLog("查询个人用户推荐职位")
    @GetMapping("/user/recommend/page")
    public R getJobInfoPage(@ParameterObject Page page, @ParameterObject String jobIntent) {
        return R.ok(jobInfoService.getRecommendJobPage(page, jobIntent));
    }

    /**
     * 查询招聘首页推荐职位
     *
     * @param page 分页条件
     * @return
     */
    @Operation(summary = "查询招聘首页推荐职位", description = "查询招聘首页推荐职位")
    @SysLog("查询招聘首页推荐职位")
    @GetMapping("/recommend/page")
    public R getRecommendPage(@ParameterObject Page page) {
        // 1. 排序规则：推广时间->置顶时间->更新时间（职位刷新）
        return R.ok(jobInfoService.getJobPage(page));
    }

    /**
     * 查询招聘首页推荐职位-开放接口
     *
     * @param page 分页条件
     * @return
     */
    @Operation(summary = "查询招聘首页推荐职位-开放接口", description = "查询招聘首页推荐职位-开放接口")
    @SysLog("查询招聘首页推荐职位-开放接口")
    @GetMapping("/recommend/page/open")
    @Inner(value = false)
    public R getRecommendPageOpen(@ParameterObject Page page) {
        // 1. 排序规则：推广时间->置顶时间->更新时间（职位刷新）
        return R.ok(jobInfoService.getJobPage(page));
    }


    /**
     * 通过条件查询职位信息表
     *
     * @param jobInfo 查询条件
     * @return R  对象列表
     */
    @Operation(summary = "通过条件查询", description = "通过条件查询对象")
    @GetMapping("/details")
    public R getDetails(@ParameterObject JobInfoEntity jobInfo) {
        return R.ok(jobInfoService.list(Wrappers.query(jobInfo)));
    }

    /**
     * 根据ID查询职位详情
     *
     * @param jobId
     * @return
     */
    @Operation(summary = "职位详情", description = "职位详情")
    @GetMapping("/{jobId}")
    @SysLog("职位详情")
    public R getJobById(@PathVariable String jobId) {
        JobInfoEntity jobInfo = jobInfoService.getById(jobId);
        if (jobInfo == null) {
            return R.failed("未查询到职位信息");
        }
        return R.ok(jobInfoService.jobDetail(jobId).getData());
    }

    /**
     * 新增职位信息表
     *
     * @param jobInfo 职位信息表
     * @return R
     */
    @Operation(summary = "新增职位信息表", description = "新增职位信息表")
    @SysLog("新增职位信息表")
    @PostMapping
    public R save(@RequestBody JobInfoEntity jobInfo) {
        return R.ok(jobInfoService.saveJobInfo(jobInfo).getData());
    }

    @Operation(summary = "当前用户可发布数量", description = "当前用户可发布数量")
    @SysLog("当前用户可发布数量")
    @GetMapping("/remainNum")
    public R getRemainNum() {
        R<Long> remainNum = jobInfoService.getRemainNum();
        if (remainNum.getCode() == CommonConstants.FAIL){
            return R.failed(remainNum.getMsg());
        }
        return R.ok(remainNum.getData());
    }

    /**
     * 修改职位信息表
     *
     * @param jobInfo 职位信息表
     * @return R
     */
    @Operation(summary = "修改职位信息表", description = "修改职位信息表")
    @SysLog("修改职位信息表")
    @PutMapping
    public R updateById(@RequestBody JobInfoEntity jobInfo) {
        return R.ok(jobInfoService.updateJobInfo(jobInfo).getData());
    }

    @Operation(summary = "修改职位刷新周期", description = "修改职位刷新周期")
    @SysLog("修改职位刷新周期")
    @GetMapping("/updateRefreshDuration/{jobId}")
    public R updateRefreshDuration(@ParameterObject Integer refreshDuration, @PathVariable String jobId) {
        R r = jobInfoService.updateRefreshDuration(refreshDuration, jobId);
        if (r.getCode() != CommonConstants.SUCCESS) {
            return R.failed(r.getMsg());
        }
        return R.ok(Boolean.TRUE);
    }

    @Operation(summary = "停止职位", description = "停止职位")
    @SysLog("停止职位")
    @GetMapping("/stopJob/{jobId}")
    public R updateRefreshDuration(@PathVariable String jobId) {
        JobInfoEntity jobInfo = jobInfoService.getById(jobId);
        if (jobInfo == null) {
            return R.failed("未查询到职位信息");
        }
        jobInfo.setStatus(JobStatusEnum.STOPPED);
        jobInfo.setStatusDesc(JobStatusEnum.STOPPED.getDescription());
        jobInfoService.updateById(jobInfo);
        return R.ok();
    }

    /**
     * 手动刷新
     *
     * @param jobId 职位ID
     * @return
     */
    @Operation(summary = "手动刷新职位", description = "手动刷新职位")
    @SysLog("手动刷新职位")
    @GetMapping("/refresh/manual/{jobId}")
    public R refreshJob(@PathVariable Long jobId) {
        R r = jobInfoService.refreshJob(jobId, "MANUAL");
        if (r.getCode() != CommonConstants.SUCCESS) {
            return R.failed(r.getData(), r.getMsg());
        }
        return R.ok();
    }

    /**
     * 通过id删除职位信息表
     *
     * @param ids id列表
     * @return R
     */
    @Operation(summary = "通过id删除职位信息表", description = "通过id删除职位信息表")
    @SysLog("通过id删除职位信息表")
    @DeleteMapping
    public R removeById(@RequestBody Long[] ids) {
        //删除redis职位更新缓存
        for (Long id : ids) {
            redisTemplate.opsForZSet().remove(JOB_REFRESH_KEY, id);
            redisTemplate.opsForHash().delete(JOB_REFRESH_INFO_PREFIX + id, "last_refreshed_at");
            redisTemplate.opsForHash().delete(JOB_REFRESH_INFO_PREFIX + id, "refresh_interval");
        }
        //删除个人收藏记录
        personalCollectService.removeByJobId(ids, SecurityConstants.FROM_IN);
        return R.ok(jobInfoService.removeBatchByIds(CollUtil.toList(ids)));
    }

    /**
     * 职位置顶
     *
     * @param jobTopVO
     * @return
     */
    @Operation(summary = "职位置顶", description = "职位置顶")
    @SysLog("职位置顶")
    @PutMapping("/top")
    public R updateTop(@Valid @RequestBody JobTopVO jobTopVO) {
        return R.ok(jobInfoService.top(jobTopVO).getData());
    }

    /**
     * 学历列表
     *
     * @return
     */
    @Operation(summary = "学历列表", description = "学历列表")
    @SysLog("学历列表")
    @GetMapping("/degree")
    public R getDegree() {
        List<Map<String, String>> list = new ArrayList<>();
        for (DegreeEnum degreeEnum : DegreeEnum.values()) {
            Map<String, String> map = new HashMap<>();
            map.put("name", degreeEnum.name());
            map.put("description", degreeEnum.getDesc());
            list.add(map);
        }
        return R.ok(list);
    }

    /**
     * 工作经验列表
     *
     * @return
     */
    @Operation(summary = "工作经验", description = "工作经验")
    @SysLog("工作经验")
    @GetMapping("/workExperience")
    public R getWorkExperience() {
        List<Map<String, String>> list = new ArrayList<>();
        for (WorkExperienceEnum degreeEnum : WorkExperienceEnum.values()) {
            Map<String, String> map = new HashMap<>();
            map.put("name", degreeEnum.getValue());
            map.put("description", degreeEnum.getDesc());
            list.add(map);
        }
        return R.ok(list);
    }

}
